﻿using System.Security.AccessControl;
using System.Security.Cryptography;
using Microsoft.Win32;

namespace 操作注册表
{
    internal class Program
    {
        /*
         在 C# 中操作注册表非常简单，常用的操作包括：
            读取注册表值：使用 Registry.GetValue
            写入注册表值：使用 Registry.SetValue
            创建/打开注册表项：使用 Registry.CreateSubKey
            删除注册表值/项：使用 RegistryKey.DeleteValue
            列出注册表项中的键/值：使用 RegistryKey.GetSubKeyNames 和 RegistryKey.GetValueNames。

          设置跟随系统自启动
           @HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run 
         */

        static void Main01(string[] args)
        {
            #region 写入值
            {
                string baseKeyPath = @"HKEY_CURRENT_USER\Software\MyApp";
                //Registry.SetValue(baseKeyPath, "State4", "hello registry", RegistryValueKind.String);
                //Console.WriteLine("写入成功");
            }
            #endregion

            #region 创建子项
            {
                //string baseKeyPath = @"Software\MyApp";
                //RegistryKey? registryKey = Registry.CurrentUser.OpenSubKey(@baseKeyPath,true);
                //registryKey.DeleteSubKey("app1",false);
                //registryKey.DeleteSubKey("app2",false);
                //registryKey.DeleteSubKey("app3",false);

                //registryKey.CreateSubKey("app1", true, RegistryOptions.Volatile);
                //registryKey.CreateSubKey("app2", true, RegistryOptions.Volatile);
                //registryKey.CreateSubKey("app3", true, RegistryOptions.Volatile);

                //string baseKey = "HKEY_CURRENT_USER\\" + baseKeyPath + "\\";
                //Registry.SetValue(baseKey + "app1","State",1,RegistryValueKind.DWord);
                //Registry.SetValue(baseKey + "app2", "State", 0,RegistryValueKind.DWord);
                //Registry.SetValue(baseKey + "app3", "State", 1,RegistryValueKind.DWord);
                //Console.WriteLine("子项创建完成");
            }
            #endregion

            #region 读取值
            {
                string baseKeyPath = @"Software\MyApp";
                RegistryKey? registryKey = Registry.CurrentUser.OpenSubKey(baseKeyPath);
                string[] keyNames = registryKey.GetSubKeyNames();
                foreach (string keyName in keyNames)
                {
                    Console.WriteLine($"key: {keyName}");
                }
                string[] valNames = registryKey.GetValueNames();
                foreach (string valName in valNames)
                {
                    object? val = registryKey.GetValue(valName);
                    Console.WriteLine($"valName: {valName},value: {val}");
                }

                RegistryKey? registryKey1 = registryKey.OpenSubKey("app1");
                Console.WriteLine($"key name: {registryKey1.Name}");
                foreach (var valName in registryKey1.GetValueNames())
                {
                    object? val = registryKey1.GetValue(valName);
                    Console.WriteLine($"valName: {valName},value: {val}");
                }

                RegistryKey? registryKey2 = registryKey.OpenSubKey("app2");
                Console.WriteLine($"key name: {registryKey2.Name}");
                foreach (var valName in registryKey1.GetValueNames())
                {
                    object? val = registryKey2.GetValue(valName);
                    Console.WriteLine($"valName: {valName},value: {val}");
                }

                RegistryKey? registryKey3 = registryKey.OpenSubKey("app3");
                Console.WriteLine($"key name: {registryKey3.Name}");
                foreach (var valName in registryKey3.GetValueNames())
                {
                    object? val = registryKey3.GetValue(valName);
                    Console.WriteLine($"valName: {valName},value: {val}");
                }
            }
            #endregion
        }
        static void Md5Test()
        {
            //string filePath = "D:/1.txt";
            string filePath = "D:\\上位机&机器视觉\\语音模型\\vosk-model-cn-0.22.zip";
            using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                using (MD5 md5 = MD5.Create())
                {
                    byte[] buff = md5.ComputeHash(fileStream);
                }
            }
        }

        static void RegTest()
        {
            //RegInfoSet();
            //RegInfoGet();
            RegistryKey? registryKey = Registry.CurrentUser.OpenSubKey(@"Software\MyApp");
            // 获取子项列表
            foreach (var keyName in registryKey.GetSubKeyNames())
            {
                object? val = registryKey.GetValue(keyName);
                Console.WriteLine($"{keyName}: {val}");
            }
            // 获取注册键的ValueNames
            foreach (var valName in registryKey.GetValueNames())
            {
                object? val = registryKey.GetValue(valName);
                if (val is byte[] b_val)
                {
                    Console.WriteLine($"{valName}: {string.Join(',', b_val)}");
                }
                else if (val is string s_val)
                {
                    Console.WriteLine($"{valName}: {s_val}");
                }
                else if (val is int i_val)
                {
                    Console.WriteLine($"{valName}: {i_val}");
                }
                else if (val is long l_val)
                {
                    Console.WriteLine($"{valName}: {l_val}");
                }

            }

            registryKey.SetValue("111", 1, RegistryValueKind.Binary);
        }

        static void RegInfoSet()
        {
            // 定义注册表路径
            string keyPath = @"HKEY_CURRENT_USER\Software\MyApp";
            //string valueName = "UserName";
            //string valueData = "JohnDoe";
            string valueName = "State";
            byte valueData = 22;

            // 创建或打开注册表项
            Registry.SetValue(keyPath, valueName, valueData);

            Console.WriteLine("Registry value written successfully.");
        }

        static void RegInfoGet()
        {
            // 定义注册表路径
            string keyPath = @"HKEY_CURRENT_USER\Software\MyApp";
            //string valueName = "UserName";
            string valueName = "State";

            // 读取指定键的值
            byte val = (byte)Registry.GetValue(keyPath, valueName, 0);

            // 输出读取的值
            Console.WriteLine($"{valueName}: {val}");
        }

        /// <summary>
        ///  闭包 是指一个函数和其捕获的外部变量的组合。它能够访问并操作这些变量，即使它们所在的作用域已经结束。
        ///  在实际应用中，闭包常用于回调、延迟执行、函数工厂等场景，提供了更强的灵活性和封装性。
        /// </summary>
        static void Closure()
        {
            Func<int> func = CreateCounter();
            Console.WriteLine(func());
            Console.WriteLine(func());
            Console.WriteLine(func());
        }

        public static Func<int> CreateCounter()
        {
            int count = 0;
            return () =>
            {
                count++;
                return count;
            };
        }

        static void Main(string[] args)
        {
            CreditCardPaymentProcess creditCardPaymentProcess = new CreditCardPaymentProcess();
            Console.WriteLine("Credit Card Payment Strategy");
            creditCardPaymentProcess.ExecutePayment();

            Console.WriteLine();
            AlipayPaymentProcess alipayPaymentProcess = new AlipayPaymentProcess();
            Console.WriteLine("Alipay Payment Strategy");
            alipayPaymentProcess.ExecutePayment();
        }
    }

    // 支付接口 (策略模式)
    public interface IPaymentStrategy
    {
        void Pay();
    }

    // 信用卡支付策略 (策略模式)
    public class CreditCardPayment : IPaymentStrategy
    {
        public void Pay()
        {
            Console.WriteLine("Processing payment through Credit Card.");
        }
    }

    // 支付宝支付策略 (策略模式)
    public class AlipayPayment : IPaymentStrategy
    {
        public void Pay()
        {
            Console.WriteLine("Processing payment through Alipay.");
        }
    }

    // 支付工厂 (工厂模式)
    public class PaymentFactory
    {
        public static IPaymentStrategy CreatePaymentStrategy(string paymentType)
        {
            switch (paymentType.ToLower())
            {
                case "creditcard":
                    return new CreditCardPayment();
                case "alipay":
                    return new AlipayPayment();
                default:
                    throw new ArgumentException("Invalid payment type");
            }
        }
    }

    // 基础支付流程 (模板方法模式)
    public abstract class PaymentProcess
    {
        // 模板方法，定义支付流程
        public void ExecutePayment()
        {
            CollectPaymentDetails();
            ProcessPayment();
            SendConfirmation();
        }

        // 收集支付信息
        protected virtual void CollectPaymentDetails()
        {
            Console.WriteLine("Collecting payment details...");
        }

        // 处理支付，使用策略模式来调用具体支付方式
        protected abstract void ProcessPayment();

        // 发送确认信息
        protected virtual void SendConfirmation()
        {
            Console.WriteLine("Sending payment confirmation...");
        }
    }

    // 信用卡支付流程 (模板方法模式)
    public class CreditCardPaymentProcess : PaymentProcess
    {
        private readonly IPaymentStrategy _paymentStrategy;

        public CreditCardPaymentProcess()
        {
            _paymentStrategy = PaymentFactory.CreatePaymentStrategy("creditcard");
        }

        // 重写处理支付
        protected override void ProcessPayment()
        {
            _paymentStrategy.Pay();
        }
    }

    // 支付宝支付流程 (模板方法模式)
    public class AlipayPaymentProcess : PaymentProcess
    {
        private readonly IPaymentStrategy _paymentStrategy;

        public AlipayPaymentProcess()
        {
            _paymentStrategy = PaymentFactory.CreatePaymentStrategy("alipay");
        }

        // 重写处理支付
        protected override void ProcessPayment()
        {
            _paymentStrategy.Pay();
        }
    }
}
